Thread: [Warning] comparison is always false due to limited range of data type

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    68

    [Warning] comparison is always false due to limited range of data type

    Hi there!

    Really, really strange, I have no clue why I get two warnings. Look at the code yourself, I splitted the lines to see where exactly the compiler (gcc) shouts:

    Code:
    int func(char *buf)
    {
    ...
    	if(buf[i] == 0xaf 
    	&& buf[i+1] == 0x00)
    		if(buf[i+2] == 0x09 
    		&& buf[i+3] == 0x00 
    		&& buf[i+4] == 0x01 
    		&& buf[i+5] == 0x00 
    		&& buf[i+6] == 0xb0
    		&& buf[i+7] == 0x00 
    		&& buf[i+38] == 0x01 
    		&& buf[i+39] == 0x00)
    ...
    }
    Only these two lines get the warning! I mean... does the compiler know the values under race conditions already before?

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Are you sure that these are the two lines??
    An Introduction to GCC - Portability of signed and unsigned types

  3. #3
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    I have read this internet page before posting.

    And yes, the compiler writes this error for line 140 and 146. It's these two lines that I highlighted.

    I wonder so much because I use the same method in the same program also, working! The problem is, the code is REALLY not working. I manually check the array "buf", and it contains the data where it should trigger, but it doesn't trigger!

    Other data does trigger though, like:

    Code:
    			if(buf[i] == 0x78 && buf[i+1] == 0x00)
    				if(buf[i+17] == 0x00 && buf[i+18] == 0x00 && buf[i+19] == 0x00 && buf[i+20] == 0x00 && buf[i+21] == 0x00
    				 && buf[i+22] == 0x00 && buf[i+23] == 0x00 && buf[i+24] == 0x00 && buf[i+25] == 0x00 && buf[i+26] == 0x00
    				  && buf[i+27] == 0x00 && buf[i+28] == 0x00 && buf[i+29] == 0x00 && buf[i+30] == 0x00 && buf[i+31] == 0x00
    				   && buf[i+32] == 0x00 && buf[i+33] == 0x00 && buf[i+34] == 0x00 && buf[i+35] == 0x00 && buf[i+36] == 0x00
    				    && buf[i+37] == 0x00 && buf[i+38] == 0x00 && buf[i+39] == 0x00 && buf[i+40] == 0x00 && buf[i+41] == 0x00
    				     && buf[i+42] == 0x00 && buf[i+43] == 0x00 && buf[i+44] == 0x00 && buf[i+45] == 0x00 && buf[i+46] == 0x00)
    and

    Code:
    			if(buf[i] == 0x2c && buf[i+1] == 0x02)
    				if(buf[i+19] == 0x00 && buf[i+20] == 0x00 && buf[i+21] == 0x00 && buf[i+22] == 0x00 && buf[i+23] == 0x00
    				 && buf[i+24] == 0x00 && buf[i+25] == 0x00 && buf[i+26] == 0x00 && buf[i+31] == 0x00 && buf[i+32] == 0x00
    				  && buf[i+33] == 0x00 && buf[i+34] == 0x00 && buf[i+35] == 0x00 && buf[i+36] == 0x00 && buf[i+37] == 0x00
    				   && buf[i+38] == 0x00 && buf[i+39] == 0x00 && buf[i+40] == 0x00 && buf[i+41] == 0x00 && buf[i+42] == 0x00)

  4. #4
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Okay I see that the warnings occur before comparing a signed char with 0xaf and 0xb0.

    I always thought, when I write 0xFF or \xFF, it doesn't matter if a number is treated as signed or unsigned because it is just a byte comparision (0xFF is always 0xFF, no matter if treated unsigned or signed, and there is no thing as -0xb0 am I right?)

    So if this is obviously the problem, how can I compare it correctly without using buf[i] == -1 instead of buf[i] == 0xFF and without casting to every compare? I don't want to calculate all hex bytes into decimal numbers just for comparision. The buffer itself also must stay signed.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    A few memcmp() calls would simplify the code, for all those consecutive runs you're comparing 1 byte at a time.

    > no matter if treated unsigned or signed, and there is no thing as -0xb0 am I right?)
    What you end up with comparing is say -64 with 0xC0, but the -64 gets promoted to signed int (still negative), not unsigned char (and positive).

    Code:
    int main ( ) {
      signed char a = -64;
      printf("%x\n",a);
      if ( a == 0xc0 ) {
        printf("Maybe\n");
      }
      if ( (unsigned char)a == 0xc0 ) {
        printf("Yes\n");
      }
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    You can make sure the buffer is declared unsigned, as in
    Code:
    int func(unsigned char *buf)

  7. #7
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    I want to avoid memcmp because the locations I want to check are random and not in a row. (Sometimes I want to check byte 1,2,3,4 but most often I want to check 1,2,9,10,23,24,25,26 which would mean also 3 times memcmp).

    Salem, nonoob, I wanted to avoid your methods.
    without casting to every compare? I don't want to calculate all hex bytes into decimal numbers just for comparision. The buffer itself also must stay signed.
    Does that mean there is no other option?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > The buffer itself also must stay signed.
    Why?
    One cast, and you can compare everything with an unsigned char and be home free.

    It's just another pointer. A smart compiler might just optimise it away.
    unsigned char *ubuf = (unsigned char *)buf;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Quote Originally Posted by Salem View Post
    > The buffer itself also must stay signed.
    Why?
    Because the code is old and long where I do many other things. Working with data as well as working with ascii chars and I don't want to check all the working code again

    Quote Originally Posted by Salem View Post
    unsigned char *ubuf = (unsigned char *)buf;
    That's exactly what I needed, thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory Leak in AppWizard-Generated Code
    By jrohde in forum Windows Programming
    Replies: 4
    Last Post: 05-19-2010, 04:24 PM
  2. LDAP Query
    By Travoiz in forum C++ Programming
    Replies: 0
    Last Post: 08-13-2009, 02:58 PM
  3. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  4. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM
  5. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM